﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEditor;
using UnityEngine;

public class AssetClass
{
    public string xiushifu;
    public string type;
    public string name;
    public string notes;
}

public class AssetWindow : EditorWindow
{
    AssetWindow()
    {
        this.titleContent = new GUIContent("CreateNewClass");
        this.maxSize = new Vector2(500, 460);
        this.minSize = new Vector2(500, 460);
    }

    [MenuItem("DevelopTool/Create ScriptableObj")]
    static void CreateTestWindows()
    {
        EditorWindow win=GetWindow(typeof(AssetWindow), false);
        //win.Close();
    }

    Vector2 scrollPos = Vector2.zero;
    List<AssetClass> assetClassList = new List<AssetClass>();
    string[] xiushifuContent = new string[2] { "public", "private" };
    string[] typeArray = new string[16] {"string","int","float","double","Transform","GameObject","Vector2",
        "Vector3","List<string>","List<int>","List<float>","List<double>","List<Transform>",
        "List<GameObject>","List<Vector2>", "List<Vector3>"};

    List<int> selectList = new List<int>();
    List<int> selectList2 = new List<int>();
    List<string> paramNameList = new List<string>();
    List<string> notesList = new List<string>();
    string className;
    string assetSavePath,classFileSavePath;
    bool isDisablePanel = false;
    bool isCheck = false;


    private void Update()
    {
        if (isCheck)
        {
            if (!EditorApplication.isCompiling)
            {
                isCheck = false;
                Check();
            }
        }
    }

    void OnGUI()
    {
        EditorGUI.BeginDisabledGroup(isDisablePanel);

        GUILayout.BeginVertical(GUILayout.Height(450));
        GUILayout.Space(10);
        scrollPos = GUILayout.BeginScrollView(scrollPos, false, true);
        for (int i = 0; i < assetClassList.Count; i++)
        {
            GUILayout.BeginHorizontal();
            GUILayout.Space(20);

            int i1= EditorGUILayout.Popup(selectList[i], xiushifuContent, GUILayout.Width(70));
            selectList[i] = i1;

            int i2= EditorGUILayout.Popup(selectList2[i], typeArray, GUILayout.Width(120));
            selectList2[i] = i2;

            string name=GUILayout.TextField(paramNameList[i], GUILayout.Width(120));
            paramNameList[i] = name;

            string notes = GUILayout.TextField(notesList[i], GUILayout.Width(100));
            notesList[i] = notes;

            if (GUILayout.Button(" - ",GUILayout.Width(25)))
            {
                selectList.RemoveAt(i);
                selectList2.RemoveAt(i);
                paramNameList.RemoveAt(i);
                notesList.RemoveAt(i);
                assetClassList.RemoveAt(i);
            }
            GUILayout.EndHorizontal();
        }
        GUILayout.EndScrollView();

        GUILayout.BeginHorizontal();
        GUILayout.Space(150);
        if (GUILayout.Button("Add Param", GUILayout.Width(120)))
        {
            selectList.Add(0);
            selectList2.Add(0);
            paramNameList.Add("ParamName");
            notesList.Add("Notes");

            AssetClass ac = new AssetClass();
            ac.xiushifu = xiushifuContent[0];
            ac.type = typeArray[0];
            ac.name = "ParamName";
            ac.notes = "Notes";
            assetClassList.Add(ac);
        }

        if (GUILayout.Button("Clear", GUILayout.Width(100)))
        {
            selectList.Clear();
            selectList2.Clear();
            paramNameList.Clear();
            notesList.Clear();
            assetClassList.Clear();
        }
        GUILayout.EndHorizontal();

        GUILayout.Space(10);
        GUILayout.BeginHorizontal();
        GUILayout.Space(150);
        GUILayout.Label("Class Name:",GUILayout.Width(80));
        className=GUILayout.TextField(className, GUILayout.Width(130));
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
        GUILayout.BeginHorizontal();
        GUILayout.Space(150);
        GUILayout.Label("Save Path:/Resources");
        GUILayout.EndHorizontal();
        GUILayout.Space(10);
        GUILayout.BeginHorizontal();
        GUILayout.Space(150);
        if(GUILayout.Button("Create", GUILayout.Width(200)))
        {
            isDisablePanel = true;
            CreateCustomClassFile();
        }
        GUILayout.EndHorizontal();

        GUILayout.EndVertical();

        EditorGUI.BeginDisabledGroup(isDisablePanel);
    }

    void CreateCustomClassFile()
    {
        
        assetSavePath = "Assets/Resources/";
        classFileSavePath = Application.dataPath + "/Scripts/GenerateScript/";

        if (ValidParam())
        {
            if (!Directory.Exists(assetSavePath))
                Directory.CreateDirectory(assetSavePath);
            if (!Directory.Exists(classFileSavePath))
                Directory.CreateDirectory(classFileSavePath);

            GenerateClassFile();
            AssetDatabase.Refresh();
            isCheck = true;
        }

    }


    void Check()
    {
        Type type = null;
        type = Assembly.Load("Assembly-CSharp").GetType(className);
        var obj = CreateInstance(type);
        AssetDatabase.CreateAsset(obj, assetSavePath + className + ".asset");
        AssetDatabase.SaveAssets();
        Debug.Log("----Success Generate ScriptableObj!----");
        Reset();
        AssetDatabase.Refresh();
    }

    void Reset()
    {
        selectList.Clear();
        selectList2.Clear();
        paramNameList.Clear();
        notesList.Clear();
        assetClassList.Clear();
        className = "";

        isDisablePanel = false;
    }

    bool ValidParam()
    {
        if (assetClassList.Count == 0)
        {
            Debug.LogError("You didn't add any param,can not create!");
            return false;
        }else
        {
            for (int i = 0; i < assetClassList.Count; i++)
            {
                if (string.IsNullOrEmpty(paramNameList[i]))
                {
                    Debug.LogError("Your Param has null or empty,can not create!");
                    return false;
                }
            }

            if (string.IsNullOrEmpty(className))
            {
                Debug.LogError("Your Class_Name is null or empty,can not create!");
                return false;
            }
            return true;
        }
    }

    void GenerateClassFile()
    {
        string filePath = classFileSavePath + className+".cs";
        if (File.Exists(filePath))
            File.Delete(filePath);
        using (StreamWriter file = new StreamWriter(filePath, false))
        {
            //类文件头部
            file.Write("using System;\n");
            file.Write("using System.Collections;\n");
            file.Write("using System.Collections.Generic;\n");
            file.Write("using UnityEngine;\n");
            file.Write("\n");
            file.Write("[Serializable]\n");
            //写入类名(与文件名相同)
            file.Write("public class ");
            file.Write(className+ ": ScriptableObject");
            file.Write("\n{\n");

            for (int i = 0; i < assetClassList.Count; i++)
            {
                file.Write("\t" + xiushifuContent[selectList[i]] + " " + typeArray[selectList2[i]] + " " + paramNameList[i] + ";//" + notesList[i]);
                file.Write("\n");
            }
            file.Write("\n}");
        }
    }
}
